package com.example.doufacedemo

import android.Manifest
import android.app.PendingIntent
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.graphics.Bitmap
import android.graphics.Matrix
import android.hardware.usb.UsbDevice
import android.hardware.usb.UsbManager
import android.os.Bundle
import android.os.Handler
import android.os.Message
import android.util.Log
import android.view.SurfaceHolder
import android.view.ViewGroup
import androidx.appcompat.app.AppCompatActivity
import com.example.doufacedemo.DouFacePayUtils.*
import com.example.doufacedemo.colordepth.SimpleViewer
import com.hjimi.api.iminect.ImiDevice
import com.hjimi.api.iminect.ImiDeviceAttribute
import com.hjimi.api.iminect.ImiDeviceState
import com.hjimi.api.iminect.ImiNect
import kotlinx.android.synthetic.main.activity_main.*
import org.bytedeco.javacpp.Pointer
import org.bytedeco.xhfacelite.global.xhfacelite
import org.bytedeco.xhfacelite.global.xhfacelite.XHF_SESS
import java.io.File
import java.io.FileOutputStream
import java.io.IOException
import java.io.InputStream
import java.lang.ref.WeakReference
import kotlin.concurrent.thread


class MainActivity : AppCompatActivity() {
    //基础权限
    companion object {
        private val PERMISSIONS = arrayOf(
            Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.WRITE_EXTERNAL_STORAGE,
//        Manifest.permission.ACCESS_WIFI_STATE,
            Manifest.permission.READ_PHONE_STATE,
            Manifest.permission.CAMERA
        )
        private val path = "/storage/emulated/0/" + "images" + System.currentTimeMillis() + ".jpg"


        private val ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION"
    }

    private var mUsbPermissionActionReceiver: BroadcastReceiver? = null
    private var bitmap: Bitmap? = null
    private lateinit var matrix: Matrix
    private var mColorViewer: SimpleViewer? = null
    private var mDeviceAttribute: ImiDeviceAttribute? = null
    private val DEVICE_OPEN_SUCCESS = 0
    private val DEVICE_OPEN_FALIED = 1
    private val DEVICE_DISCONNECT = 2
    private var mDevice: ImiDevice? = null
    private var mUsbManager: UsbManager? = null
    private var mSurfaceHolder: SurfaceHolder? = null
    private var usb: UsbReceriver? = null
    private var xhf_sess: XHF_SESS? = null
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        //初始化
//        thread { copyAssetsDir2Phone("models") }
//

        val filter = IntentFilter(ACTION_USB_PERMISSION)
        usb = UsbReceriver()
        this.registerReceiver(usb, filter)

//        requestPermissionsEx(*PERMISSIONS) {
//            thread {
//                val xh_code = xhfacelite.XHFInit(
//                    getExternalFilesDir("Face2").toString(),
//                    "xhtest2020"
//                )
//                Log.i("main", "initCode  = " + xh_code)
//
//            }
//        }
        initDou()
        btn_intert.setOnClickListener {
           //创建窗口-插入-保存
            //插入到内存
            faceIntert(xhf_sess)
            //插入到本地
            faceSave(xhf_sess, MyApp.mContext)
        }
        btn_open_carmer.setOnClickListener {
            //开启摄像头
            Thread(OpenDeviceRunnable()).start()
        }
        btn_get_usb.setOnClickListener {
            //申请权限
            tryGetUsbPermission()
        }
        btn_close_carmere.setOnClickListener {
            //关闭摄像头 回收资源
            Thread( ExitRunnable()).start()
        }
        matrix = Matrix()
        val w = 0.8.toFloat()
        val y = 0.8.toFloat()
        matrix.postScale(w, y)
        matrix.postScale(-1f, 1f)


    }

    private fun initDou() { //3 第一次初始化算法，可以不用执行第3 的程序
        // 加载接口：xhfacelite.FELoad
        Thread(Runnable {
            val xh_code = xhfacelite.XHFInit(
                getExternalFilesDir("Face2").toString(),
                "xhtest2020"
            )
            Log.i("main", "步骤1:初始化  = $xh_code")
            xhf_sess = FECreate()
            FEload()
        }).start()
    }
    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<out String>,
        grantResults: IntArray
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        if (requestCode == REQUEST_ALL_PERMISSION) {
            if (hasPermissions(*PERMISSIONS)) {

            } else {
                requestPermissionsEx(*PERMISSIONS)
            }
        }

    }


    //写文件到指定目录
    fun copyAssetsDir2Phone(filePath: String) {
        var filePath = filePath
        try {
            val fileList: Array<String> = assets.list(filePath)!!
            if (fileList.size > 0) { //如果是目录
                val file =
                    File(filesDir.absolutePath + File.separator.toString() + filePath)
                file.mkdirs() //如果文件夹不存在，则递归
                for (fileName1 in fileList) {
                    filePath = filePath + File.separator.toString() + fileName1
                    copyAssetsDir2Phone(filePath)
                    filePath = filePath.substring(0, filePath.lastIndexOf(File.separator))
                }
            } else { //如果是文件
                val inputStream: InputStream = assets.open(filePath)
                val file = File(
                    getExternalFilesDir("Face2").toString() + File.separator.toString() + filePath.substring(
                        7
                    )
                )
                if (!file.exists()) {
                    val fos = FileOutputStream(file)
                    var len = -1
                    val buffer = ByteArray(1024)
                    while (inputStream.read(buffer).also({ len = it }) != -1) {
                        fos.write(buffer, 0, len)
                    }
                    fos.flush()
                    inputStream.close()
                    fos.close()
                } else {

                }
            }
        } catch (e: IOException) {
            e.printStackTrace()
        }
    }


    inner class OpenDeviceRunnable : Runnable {
        override fun run() { //get iminect instance.
            ImiNect.initialize()
            mDevice = ImiDevice.getInstance()
            val mainlistener = MainListener()
            mDevice?.open(this@MainActivity, 0, mainlistener)
            mDevice?.addDeviceStateListener(mainlistener)
        }
    }

    inner class MainListener : ImiDevice.OpenDeviceListener, ImiDevice.DeviceStateListener {
        override fun onOpenDeviceSuccess() {
            Log.i("sss", "打开设备成功")
            MainHandler.sendEmptyMessage(DEVICE_OPEN_SUCCESS)
        }

        override fun onOpenDeviceFailed(errorMsg: String) { //open device falied.
            Log.i("sss", "打开设备失败$errorMsg")
        }

        override fun onDeviceStateChanged(
            deviceInfo: String,
            state: ImiDeviceState
        ) {

        }
    }

    inner class MyHandler(activity: MainActivity) : Handler() {
        var mActivity: WeakReference<MainActivity> = WeakReference(activity)
        override fun handleMessage(msg: Message) {
            val mainActivity = mActivity.get()
            when (msg.what) {
                DEVICE_OPEN_SUCCESS -> mainActivity?.runViewer()
            }
        }

    }

    fun runViewer() {
        val sess = XHF_SESS(Pointer())
        val code = xhfacelite.FECreate(sess)
        val ELoadcode: Int = xhfacelite.FELoad(
                sess,
                getExternalFilesDir("FaceDB").toString() + File.separator + "face_db"
            )
        Log.i("main","创建窗口 = "+code)
        Log.i("main","加载算法 = "+ELoadcode)
        mDeviceAttribute = mDevice!!.attribute
        //mTVAttrs.setText("Device SerialNumber : " + mDeviceAttribute.getSerialNumber());
        var bPortrait = false
        if (mDeviceAttribute != null && mDeviceAttribute!!.isPortraitDevice) {
            bPortrait = true
        }
        // set color frame mode
        val colorFrameMode =
            mDevice!!.getCurrentFrameMode(ImiDevice.ImiStreamType.COLOR)
        mDevice!!.setFrameMode(ImiDevice.ImiStreamType.COLOR, colorFrameMode)
        Log.d(
            "$$$$$$$$$",
            "color frame:" + colorFrameMode.resolutionX + ", " + colorFrameMode.resolutionY
        )
        mColorViewer = SimpleViewer(mDevice, ImiDevice.ImiStreamType.COLOR)
        mColorViewer?.setGLPanel(sv_attend_camera)
        mColorViewer?.setPreviewCallback { data, width, height ->
            //回调的帧图做转码处理
            bitmap = rgb2Bitmap(data, width, height)
            dealBitmap(bitmap, matrix,sess)
        }
        val colorParam: ViewGroup.LayoutParams = sv_attend_camera.layoutParams
        colorParam.width = colorFrameMode.resolutionX
        colorParam.height = colorFrameMode.resolutionY
        if (bPortrait) {
            colorParam.width = 300
            colorParam.height = 400
        }
        sv_attend_camera.layoutParams = colorParam

        mColorViewer!!.onStart()

        mDevice!!.startStream(ImiDevice.ImiStreamType.DEPTH.toNative() or ImiDevice.ImiStreamType.COLOR.toNative())

    }

    private val MainHandler = MyHandler(this)
    override fun onDestroy() {
        super.onDestroy()
        //销毁会话接口：
        val FEDestroyCode = xhfacelite.FEDestroy(MyApp.sess)
        Log.i("main", "销毁 = " + FEDestroyCode)
        xhfacelite.XHFFinal()
        mColorViewer?.onDestroy()
        unregisterReceiver(usb)
    }

    override fun onResume() {
        super.onResume()
        mColorViewer?.onResume()
    }

    override fun onPause() {
        super.onPause()
        mColorViewer?.onPause()

    }

    /**
     * 停止识别
     * */
    fun stopIdentify() {

    }

    /**
    * 获取权限
    * */
    fun tryGetUsbPermission() {

        mUsbPermissionActionReceiver = object : BroadcastReceiver() {
            override fun onReceive(context: Context?, intent: Intent?) {
                val action = intent?.action;
                if (ACTION_USB_PERMISSION.equals(action)) {
                    context?.unregisterReceiver(this);//解注册
                    synchronized(this) {
                        val usbDevice =
                            intent.getParcelableExtra<UsbDevice>(UsbManager.EXTRA_DEVICE)
                        if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
                            if (usbDevice != null) {
                                Log.e("TAG", usbDevice.getDeviceName() + "已获取USB权限");
                            } else {
                                Log.e("TAG", "usbDevice为null");
                            }
                        } else {
                            //user choose NO for your previously popup window asking for grant perssion for this usb device
                            Log.e("TAG", "USB权限已被拒绝，Permission denied for device" + usbDevice);
                        }
                    }

                }
            }

        }
        mUsbManager = getSystemService(Context.USB_SERVICE) as UsbManager

        val filter = IntentFilter( ACTION_USB_PERMISSION)

        if (mUsbPermissionActionReceiver != null) {
            registerReceiver(mUsbPermissionActionReceiver, filter)
        }

        val mPermissionIntent =
            PendingIntent.getBroadcast(this, 0, Intent( ACTION_USB_PERMISSION), 0)

        var has_idcard_usb = false
        for (usbDevice in mUsbManager!!.deviceList.values) {
            if (usbDevice.vendorId == 11707 && usbDevice.productId == 518) //身份证设备USB
            {
                has_idcard_usb = true
                Log.e("TAG", usbDevice.deviceName + "已找到身份证USB")
                if (mUsbManager!!.hasPermission(usbDevice)) {
                    Log.e("TAG", usbDevice.deviceName + "已获取过USB权限")
                } else {
                    Log.e("TAG", usbDevice.deviceName + "请求获取USB权限")
                    mUsbManager!!.requestPermission(usbDevice, mPermissionIntent)
                }
            }
        }

        if (!has_idcard_usb) {
            Log.e("TAG", "未找到身份证USB")
        }
    }
    inner private class ExitRunnable : Runnable {
        override fun run() {
            if (mColorViewer != null) {
                mColorViewer?.onPause()
            }
            //destroy color viewer.
            if (mColorViewer != null) {
                mColorViewer?.onDestroy()
            }
            if (mDevice != null) {
                mDevice?.close()
                mDevice = null
                ImiDevice.destroy()
            }
            ImiNect.destroy()
        }
    }

}



